//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cqw.redistest;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class RedisManager {
    private final Logger logger = LoggerFactory.getLogger(RedisManager.class);
    private final RedisTemplate<String, Object> redisTemplate;
    private static final String unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\nthen\n    return redis.call(\"del\",KEYS[1])\nelse\n    return 0\nend";

    public RedisManager(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public boolean expire(String key, long time) {
        try {
            if (time > 0L) {
                this.redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }

            return true;
        } catch (Exception var5) {
            return false;
        }
    }

    public Long getExpire(String key) {
        return this.redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    public Boolean hasKey(String key) {
        try {
            return this.redisTemplate.hasKey(key);
        } catch (Exception var3) {
            return false;
        }
    }

    public void delete(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                this.redisTemplate.delete(key[0]);
            } else {
                this.redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }

    }

    public Object get(String key) {
        return key == null ? null : this.redisTemplate.opsForValue().get(key);
    }

    public boolean set(String key, Object value) {
        try {
            this.redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception var4) {
            this.logger.error("redis error :", var4);
            return false;
        }
    }

    public boolean set(String key, Object value, long expire) {
        return this.set(key, value, expire, TimeUnit.SECONDS);
    }

    public boolean set(String key, Object value, long expire, TimeUnit timeUnit) {
        try {
            if (expire > 0L) {
                this.redisTemplate.opsForValue().set(key, value, expire, timeUnit);
            } else {
                this.set(key, value);
            }

            return true;
        } catch (Exception var7) {
            this.logger.error("redis error", var7);
            return false;
        }
    }

    public String getString(String key) {
        return key == null ? null : (String)this.redisTemplate.opsForValue().get(key);
    }

    public Integer getInteger(String key) {
        return key == null ? null : (Integer)this.redisTemplate.opsForValue().get(key);
    }

    public Long getLong(String key) {
        return key == null ? null : (Long)this.redisTemplate.opsForValue().get(key);
    }

    public Double getDouble(String key) {
        return key == null ? null : (Double)this.redisTemplate.opsForValue().get(key);
    }

    public long incr(String key) {
        return this.incr(key, 1L);
    }

    public long incr(String key, long increment) {
        RedisAtomicLong atomicLong = new RedisAtomicLong(key, this.redisTemplate.getConnectionFactory());
        return atomicLong.getAndAdd(increment);
    }

    public long incr(String key, long increment, long timeout) {
        long result = this.incr(key, increment);
        this.expire(key, timeout);
        return result;
    }

    /** @deprecated */
    @Deprecated
    public String lock(String name, long expire, long timeout) {
        long startTime = System.currentTimeMillis();

        String token;
        do {
            token = this.tryLock(name, expire);
            if (token == null) {
                if (System.currentTimeMillis() - startTime > timeout - 50L) {
                    break;
                }

                try {
                    Thread.sleep(50L);
                } catch (InterruptedException var10) {
                    var10.printStackTrace();
                    return null;
                }
            }
        } while(token == null);

        return token;
    }

    /** @deprecated */
    @Deprecated
    public String tryLock(String name, long expire) {
        String token = UUID.randomUUID().toString();
        RedisConnectionFactory factory = this.redisTemplate.getConnectionFactory();
        RedisConnection conn = factory.getConnection();

        try {
            Boolean result = conn.set(name.getBytes(StandardCharsets.UTF_8), token.getBytes(StandardCharsets.UTF_8), Expiration.from(expire, TimeUnit.MILLISECONDS), SetOption.SET_IF_ABSENT);
            if (result != null && result) {
                String var8 = token;
                return var8;
            }
        } finally {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }

        return null;
    }

    /** @deprecated */
    @Deprecated
    public boolean unlock(String name, String token) {
        byte[][] keysAndArgs = new byte[][]{name.getBytes(Charset.forName("UTF-8")), token.getBytes(Charset.forName("UTF-8"))};
        RedisConnectionFactory factory = this.redisTemplate.getConnectionFactory();
        RedisConnection conn = factory.getConnection();

        try {
            Long result = (Long)conn.scriptingCommands().eval("if redis.call(\"get\",KEYS[1]) == ARGV[1]\nthen\n    return redis.call(\"del\",KEYS[1])\nelse\n    return 0\nend".getBytes(StandardCharsets.UTF_8), ReturnType.INTEGER, 1, keysAndArgs);
            if (result != null && result > 0L) {
                boolean var7 = true;
                return var7;
            }
        } finally {
            RedisConnectionUtils.releaseConnection(conn, factory);
        }

        return false;
    }

    public Object execute(String script, List<String> keys, Object... params) {
        DefaultRedisScript<ArrayList<String>> defaultRedisScript = new DefaultRedisScript(script, ArrayList.class);
        return this.redisTemplate.execute(defaultRedisScript, keys, params);
    }

    public void excuteExpire(List<String> keys, long timeout) {
        String script = "for i, v in pairs(KEYS) do  redis.call('expire', KEYS[i],tonumber(ARGV[1]));   end;";
        this.execute(script, keys, String.valueOf(timeout));
    }

    public void expire(List<String> keys, long timeout) {
        keys.forEach((key) -> {
            this.expire(key, timeout);
        });
    }
}
